#!/usr/bin/env python3

from itertools import cycle
from itertools import chain
from recipes import take
import os
import webbrowser
import uuid
import random
import shutil
import argparse
from iterlib import *
#from gooey import Gooey


def flip_tuple(t):
    (a, b) = t
    return (b, a)


def list_index(l):
    "Make index for l that maps the item value to its position in l"
    return dict(map(flip_tuple, enumerate(l)))


octaves = [r" ", r"'", r"''", r"'''"]
octave_to_number = list_index(octaves)
num_octaves = len(octaves)


def choose_octaves(number_of_them):
    os = take(number_of_them, cycle(octaves))
    random.shuffle(os)
    return os


def choose_chromatics(number_of_them):
    notes = take(number_of_them, cycle(scales))
    # scale or scales above?
    return notes


def octave_inc_wrapping(o):
    n = octave_to_number[o] + 1
    if n >= num_octaves:
        n2 = 0
    else:
        n2 = n
    return octaves[n2]


scales = ["c", "cs", "d", "ds", "e", "f", "fs", "g", "gs", "a", "as", "b"]
scale_to_number = list_index(scales)
num_scales = len(scales)


def scale_and_octave_to_number(so):
    (s, o) = so
    return scale_to_number[s] + octave_to_number[o] * num_scales

def wrapping_number_to_scale_and_octave(num):
    (onum, snum) = divmod(num, num_scales) 
    if onum >= num_octaves:
        onum = onum % num_octaves
    return (scales[snum], octaves[onum])

def fix_octave(previous, current):
    if previous:
        if scale_and_octave_to_number(current) - scale_and_octave_to_number(previous) == 1:
            return wrapping_number_to_scale_and_octave(scale_and_octave_to_number(current) + 12)
        else:
            return current
    else:
        return current

def concatenate_notes_and_octaves(amount):
    noters = choose_chromatics(amount)
    number = choose_octaves(amount)
    return map_with_previous_result(fix_octave, None, zip(noters, number))
    # return map_with_previous(fix_octave, zip(noters, number), [("c", "'"), ("c", "'")])


#@Gooey
def main():
    my_parser = argparse.ArgumentParser()
    my_parser.add_argument("--chroma", action="store", type=int, required=True)
    my_parser.add_argument("--rhythm", action="store", type=int, required=True)
    # my_parser.add_argument("--id", action="store", type=int)
    args = my_parser.parse_args()
    amount = args.chroma
    timer = args.rhythm
    result = concatenate_notes_and_octaves(amount)
    print_notes(result, timer)

def print_notes(result, timer):


    res = ["".join(tup) for tup in result]
    timer2 = str(timer)
 
    filename = uuid.uuid4().hex + ".ly"
    f = open(filename,"a+")
 
    f.write(r'\language "english"')
    f.write(r'\version "2.19.82"')
    f.write(r'\include "lit.ily"')
 
    f.write("\n")
    f.write(r"\score")
    f.write(r"{")
    f.write("\n")
    f.write(r"\new PianoStaff <<")
    f.write(r'\new Staff = "up" {')
    f.write(r"\time 3/4")
    f.write("\n")
    f.write(r'\clef "treble"')
 
    for n in res:
        if r"'" in n:
            f.write(r'\change Staff = "up"')
            f.write(n + timer2)
 
        elif r"''" in n:
            f.write(r'\change Staff = "up"')
            f.write(n + timer2)
 
        elif r"'''" in n:
            f.write(n + timer2)
 
        elif r"," in n:
            f.write(r'\change Staff = "down"')
            f.write(n + timer2)
 
        elif r",," in n:
            f.write(r'\change Staff = "down"')
            f.write(n + timer2)
 
        elif r",,," in n:
            f.write(r'\change Staff = "down"')
            f.write(n + timer2)
 
        else:
            f.write(r'\change Staff = "down"')
            f.write(n + timer2)
 
    f.write("\n")
    f.write(r"}")
    f.write("\n")
 
    f.write(r'\new Staff = "down" {')
    f.write(r"\time 3/4")
    f.write(r'\clef "bass"')
 
    for n in res:
        f.write("s" + timer2)
 
    f.write(r"}")
    f.write(r">>")
    f.write("\n")
    f.write(r"\layout { }")
    f.write(r"\midi { }")
    f.write(r"}")
 
    f.close()
 
    lilypond = "lilypond " + filename 
    os.system(lilypond)
    webbrowser.open_new(filename[:-3] + ".pdf")
 
    # pdf_viewer = "zathura " + "*.pdf"
    # os.system(pdf_viewer)
 
    # midi_player = "mscore " + "*.midi"
    # os.system(midi_player)
 
    #os.mkdir(filename[:-3])
    #shutil.move(filename, filename[:-3])
    #shutil.move(filename[:-3] + ".pdf", filename[:-3])
    #shutil.move(filename[:-3] + ".midi", filename[:-3])
    #shutil.move(filename[:-3], "generations/")


if __name__ == "__main__":
    main()
